<?php

use Workerman\Worker;
use Workerman\Lib\Timer;

include __DIR__ . '/vendor/autoload.php';
//创建一个变量存放所有房间
$connection_all = [];
$timer_all = [];
//创建一个Worker监听127.0.0.1:16670, 使用websocket协议通讯  
$ws_worker = new Worker("websocket://0.0.0.0:16670");
//启动4个进程对外提供服务  
$ws_worker->count = 1;
$ws_worker->onConnect = function($connection) use($ws_worker, &$connection_all) {
    echo "\n" . $connection->getRemoteIp() . "连接服务器!\n";
};
//当接收到客户端发来的数据后显示数据并回发到客户端 
 
$ws_worker->onMessage = function($connection, $data) use ($ws_worker, &$connection_all, &$timer_all) {
    // $baseUrl = "http://test.anoqo.cn/";
    $baseUrl = "http://192.168.10.224/";
    $ip = $connection->getRemoteIp();
    if ($ip == '127.0.0.1') {
        $data = str_replace('\\"', '"', str_replace('\r\n', '', $data));
        $data = ltrim($data, '"');
        $data = rtrim($data, '"');
    }
    echo "\n收到{$ip}发来消息\n";
    //显示数据  
    echo "you just received:     $data\n";
    //判断数据是不是@
    if ($data == '@') {
        $connection->send('@');
    }
    //解析数据
    $dataInfo = json_decode($data, true);
    if (isset($dataInfo['account_id']))
        $connection_all[$dataInfo['account_id']] = $connection->id; //保存连接    
//数据分发
    if ($dataInfo && isset($dataInfo['operation'])) {
        switch ($dataInfo['operation']) {
            case "CreateRoom"://创建房间
                $url = $baseUrl . "game.php/Thirteenwater/CreateRoom";
                if(isset($dataInfo['account_id'])){
                	echo "account_id：{$dataInfo['account_id']}创建房间中……";
                }
                $httpData = https_post($data, $url);
                //给客户端推创建房间成功消息
                echo "得到参数:";
                var_dump($dataInfo);
                echo "\n返回：";
                var_dump($httpData);
                $connection->send($httpData);
                $httpData='';
                unset($httpData);
                break;
            case "PrepareJoinRoom"://有人成功进入房间围观，则向在线人员推送更新后的消息
                //请求控制器
                echo "接收时间：";
               	var_dump(time());
                $url = $baseUrl . "game.php/Thirteenwater/PrepareJoinRoom";
                $returnData = https_post($data, $url);
                //向客户端推送数据
                $connection->send($returnData);
                $returnData=json_decode($returnData);
                if(isset($returnData->result) && $returnData->result==0 && $returnData->operation=='PrepareJoinRoom'){
                	if(isset($returnData->players) && is_array($returnData->players)){
                		$returnData->operation='pull_PrepareJoinRoom';
                		$playersCount=0;//准备好的人数
                		foreach ($returnData->players as $player) {
                			$id=$player->id;
                			if(isset($returnData->data->roomStatus) && $returnData->data->roomStatus==0 && $player->account_status>=2){
                				$playersCount+=1;
                			}
                			//给除了自己以外的玩家推自己的游戏信息
                			if ($id != $dataInfo['account_id'] && isset($connection_all[$id])) {
                				echo "\n准备给玩家: {$id} 推消息, 找到的连接是: {$connection_all[$id]}\n";
                				if ($ws_worker->connections[$connection_all[$id]]){
                					$ws_worker->connections[$connection_all[$id]]->send(json_encode($returnData));
                				}
                			}
                		}
                		echo "准备好的人数：$playersCount";
                		//如果roomStatus=0 ，且有两名以上的玩家坐下，就出现开始按钮
                		if($playersCount>1 && isset($returnData->data->roomStatus) && $returnData->data->roomStatus==0 ){
                			if ($ws_worker->connections[$connection_all[$returnData->data->account_id]]){
                					$button=['result'=>0, "operation"=>'StartGame', 'data'=>['button'=>true], 'result_message'=>'显示开始按钮'];
                					echo '给房主推开始按钮：';
                					echo $returnData->data->account_id;
                					var_dump($button);
                					if($ws_worker->connections[$connection_all[$returnData->data->account_id]]){
                						echo '连接存在，发送显示按钮';
                						$ws_worker->connections[$connection_all[$returnData->data->account_id]]->send(json_encode($button));
                					}
                					$button='';
                					unset($button);
                				}
                		}
                		$playersCount='';
                		unset($playersCount);
                	}
                }
                $id='';
                $returnData = '';
                unset($returnData,$id);
                echo "结束时间：";
                var_dump(time());
                break;
            case "SitDown"://在房间坐下 另外给房主发一条开始的消息
                //请求控制器
                $url = $baseUrl . "game.php/Thirteenwater/SitDown";
                $returnData = https_post($data, $url);
                //向客户端推送数据  
                $connection->send($returnData);
                $returnData=json_decode($returnData);
                if(isset($returnData->result) && $returnData->result==0 && $returnData->operation=='SitDown'){
                	if(isset($returnData->players) && is_array($returnData->players)){
                		$returnData->operation='pull_SitDown';
                		$playersCount=0;//准备好的人数
                		foreach ($returnData->players as $player) {
                			$id=$player->id;
                			if(isset($returnData->data->roomStatus) && $returnData->data->roomStatus==0 && $player->account_status>=2){
                				$playersCount+=1;
                			}
                			//给除了自己以外的玩家推自己的游戏信息
                			if ($id != $dataInfo['account_id'] && isset($connection_all[$id])) {
                				echo "\n准备给玩家: {$id} 推消息, 找到的连接是: {$connection_all[$id]}\n";
                				if ($ws_worker->connections[$connection_all[$id]]){
                					$ws_worker->connections[$connection_all[$id]]->send(json_encode($returnData));
                				}
                			}
                		}
                		echo "坐下操作，准备好的人数：$playersCount";

                		//如果roomStatus=0 ，且有两名以上的玩家坐下，就出现开始按钮
                		if($playersCount>1 && isset($returnData->data->roomStatus) && $returnData->data->roomStatus==0 ){
                			if ($ws_worker->connections[$connection_all[$returnData->data->account_id]]){
                					$button=['result'=>0, "operation"=>'StartGame', 'data'=>['button'=>true], 'result_message'=>'显示开始按钮'];
                					echo '给房主推开始按钮：';
                					echo $returnData->data->account_id;
                					var_dump($button);
                					if($ws_worker->connections[$connection_all[$returnData->data->account_id]]){
                						echo '连接存在，发送显示按钮';
                						$ws_worker->connections[$connection_all[$returnData->data->account_id]]->send(json_encode($button));
                					}
                					
                					$button='';
                					unset($button);
                				}
                		}
                		$playersCount='';
                		unset($playersCount);
                	}
                }
                $id='';
                $returnData = '';
                unset($returnData,$id);
                break;
            case "StandUp"://站起围观
                //请求控制器
                $url = $baseUrl . "game.php/Thirteenwater/StandUp";
                $returnData = https_post($data, $url); 
                //向客户端推送数据  
                $connection->send($returnData);
                $returnData=json_decode($returnData);
                if(isset($returnData->result) && $returnData->result==0 && $returnData->operation=='StandUp'){
                	if(isset($returnData->players) && is_array($returnData->players)){
                		$returnData->operation='pull_StandUp';
                		foreach ($returnData->players as $player) {
                			$id=$player->id;
                			//给除了自己以外的玩家推自己的游戏信息
                			if ($id != $dataInfo['account_id'] && isset($connection_all[$id])){
                				echo "\n准备给玩家: {$id} 推消息, 找到的连接是: {$connection_all[$id]}\n";
                				if ($ws_worker->connections[$connection_all[$id]]){
                					$ws_worker->connections[$connection_all[$id]]->send(json_encode($returnData));
                				}
                			}
                		}
                	}
                }
                $id='';
                $returnData = '';
                unset($returnData,$id);
                break;
            case "GameStart"://游戏开始
                //请求控制器
                $url = $baseUrl . "game.php/Thirteenwater/GameStart";
                $returnData = https_post($data, $url);
                //向客户端推送数据  
                $connection->send($returnData);
                $returnData=json_decode($returnData);
                if(isset($returnData->result) && $returnData->result==0 && $returnData->operation=='GameStart'){
                	if(isset($returnData->players) && is_array($returnData->players)){
                		$returnData->operation='pull_GameStart';
                		foreach ($returnData->players as $player) {
                			$id=$player->id;
                			//给除了自己以外的玩家推自己的游戏信息
                			if (isset($connection_all[$id]) && $id != $dataInfo['account_id']) {
                				echo "\n准备给玩家: {$id} 推消息, 找到的连接是: {$connection_all[$id]}\n";
                				if ($ws_worker->connections[$connection_all[$id]]){
                					$ws_worker->connections[$connection_all[$id]]->send(json_encode($returnData));
                				}
                			}
                		}
                	}
                }
                $id='';
                $returnData = '';
                unset($returnData,$id);
                break;
            case "ShowCard"://玩家手动摊牌
                isset($dataInfo['data']['room_id']) ? $room_id = $dataInfo['data']['room_id'] : $room_id = 0;
//请求控制器
                $url = $baseUrl . "game.php/Thirteenwater/PlayerShowCard";
                $returnData = https_post($data, $url);
				var_dump(['PlayerShowCard_request' => $returnData]);
//向客户端推送数据 
                $returnArr = json_decode($returnData, true);
                if (is_array($returnArr)) {
                    foreach ($returnArr as $key => $val) {
                        foreach ($val['to'] as $k => $v) {
                            if (isset($connection_all[$v]) && isset($ws_worker->connections[$connection_all[$v]])) {
                                if (isset($ws_worker->connections[$connection_all[$v]]))
                                    $ws_worker->connections[$connection_all[$v]]->send(json_encode($val['data']));
                            }
                        }
                        if (isset($val['data']['operation']) && $val['data']['operation'] == 'Win') {
                            Timer::del($timer_all[4][$room_id]);
                            unset($timer_all[1][$room_id]);
                            unset($timer_all[2][$room_id]);
                            unset($timer_all[3][$room_id]);
                            unset($timer_all[4][$room_id]);
                        }
                    }
                }
                $result = '';
                $resultArr = '';
                unset($result, $resultArr);
                break;
            case "Controller"://控制器发送
//向客户端推送数据  
                if (isset($dataInfo['to'])) {
                    foreach ($dataInfo['to'] as $key => $value) {
                        if (isset($connection_all[$value])) {
                            if (isset($ws_worker->connections[$connection_all[$value]]))
                                $ws_worker->connections[$connection_all[$value]]->send(json_encode($dataInfo['data']));
                        }
                    }
                }
                break;
            case 'BroadcastVoice':
                BroadcastVoice($data);
                break;
            default:
                break;
//$returnData = json_encode($dataInfo);
        }
    }
};

$ws_worker->onClose = function($connection) use($ws_worker, &$connection_all, &$timer_all) {
    $conn_key = array_search($connection->id, $connection_all);
    // $onlineUrl = "http://test.anoqo.cn/game.php/Thirteenwater/GetOffLine";
    echo 'leave line is'.$conn_key;
    $onlineUrl = "http://localhost/game.php/Thirteenwater/GetOffLine";
    $returnData = https_post(json_encode(['account_id' => $conn_key, 'online_status' => 0]), $onlineUrl); //把玩家数据更新到数据库并且取得新的房间数据
    $returnData = json_decode($returnData);
    var_dump($connection_all);
    if(isset($returnData->result) && $returnData->result==0 && $returnData->operation=='GetOffLine'){
    	if(isset($returnData->players) && is_array($returnData->players)){
    		foreach ($returnData->players as $player) {
    			$id=$player->id;
    			//给在线的玩家推自己的游戏信息
    			if (isset($connection_all[$id]) && $id != $conn_key){
    				echo "\n准备给玩家: {$id} 推消息, 找到的连接是: {$connection_all[$id]}\n";
    				if ($ws_worker->connections[$connection_all[$id]]){
    					$ws_worker->connections[$connection_all[$id]]->send(json_encode($returnData));
    				}
    			}
    		}
    		$id='';
    		unset($id);
    	}
    }
    if ($conn_key) {
        $connection_all[$conn_key] = '';
        unset($connection_all[$conn_key]);
        $key = null;
        unset($conn_key);
    }
    $returnData='';
    unset($returnData);
    echo "\n onClose触发操作结束：\n";
};

//运行worker  
$ws_worker->runAll();

function BroadcastVoice($data) {
    $url = 'http://test.anoqo.cn/game.php/Thirteenwater/BroadcastVoice';
    $result = https_post($data, $url);
    var_dump(['BroadcastVoice_http_result' => $result]);
    $result = json_decode($result, true);
    if (is_array($result) && isset($result['to'])) {//如果能解析成功，即转发消息
        send2room($result['to'], json_encode($result['data']));
    }
}

function GameResult($room_id) {//发送房间的游戏结果
//请求本局结果推送
    $url = 'http://test.anoqo.cn/game.php/Thirteenwater/GameResult';
    $result = https_post(json_encode(['room_id' => $room_id]), $url);
    $data = https_post(json_encode(['room_id' => $room_id]), $url);
    if (is_array($data)) {//如果能解析成功，即转发消息
        send2room($data['to'], json_encode($data['data']));
    }
    if (isset($timer_all[$room_id]))
        Timer::del($timer_all[$room_id]); //删除原来的定时器
    $result = '';
    $data = '';
    unset($result, $data);
}

function AutoStartShow($room_id, $timer_all) {//自动摊牌回调函数
    $url = 'http://test.anoqo.cn/game.php/Thirteenwater/AutoStartShow';
    $result = https_post(json_encode(['room_id' => $room_id]), $url);
    var_dump(['AutoStartShow_result' => $result]);
    $data = json_decode($result, true);
    if (is_array($data)) {//如果能解析成功，即转发消息
        foreach ($data as $k => $v) {
            if (isset($v['to']))
                send2room($v['to'], json_encode($v['data']));
        }
    }
    $result = '';
    $data = '';
    unset($result, $data);
    unset($timer_all[1][$room_id]);
    unset($timer_all[2][$room_id]);
    unset($timer_all[3][$room_id]);
    unset($timer_all[4][$room_id]);
}

function AutoStartMultiples($room_id, $timer_all) {//自动下注回调函数
    echo "\n执行了AutoStartMultiples函数,接收到的参数值：{$room_id}  " . time() . "\n";
    $url = 'http://test.anoqo.cn/game.php/Thirteenwater/AutoStartMultiples';
    $result = https_post(json_encode(['room_id' => $room_id]), $url);
    var_dump(['AutoStartMultiples_result' => $result]);
    $data = json_decode($result, true);

    if (is_array($data)) {
        foreach ($data as $k => $v) {//如果能解析成功，即转发消息
            send2room($v['to'], json_encode($v['data']));
        }
    }
    $result = '';
    $data = '';
    unset($result, $data);

    unset($timer_all[3][$room_id]);
}

//发起一个抢庄请求，带薪上room_id
function GameStartTime($room_id, $timer_all) {
    echo "\n执行了GameStartTime函数,接收到的参数值：{$room_id}  " . time() . "\n";
    $url = 'http://test.anoqo.cn/game.php/Thirteenwater/GameStartTime';
    $result = https_post(json_encode(['room_id' => $room_id]), $url);
    var_dump(['GameStartTime_result' => $result]);
    $data = json_decode($result, true);
    if (is_array($data)) {//如果能解析成功，即转发消息
        foreach ($data as $k => $v) {
            send2room($v['to'], json_encode($v['data']));
        }
    }
    $result = '';
    $data = '';
    unset($result, $data);
    unset($timer_all[2][$room_id]);
}

//游戏自动开始回调函数
function GameAutoStart($room_id, $timer_all) {
    echo "\n执行了GameAutoStart函数,接收到的参数值：{$room_id}  " . time() . "\n";
    $url = 'http://test.anoqo.cn/game.php/Thirteenwater/GameAutoStart';
    $result = https_post(json_encode(['room_id' => $room_id]), $url);
    var_dump(['GameAutoStart_result' => $result]);
    $data = json_decode($result, true);
    if (is_array($data)) {//如果能解析成功，即转发消息
        foreach ($data as $k => $v) {
            send2room($v['to'], json_encode($v['data']));
        }
    }
    $result = '';
    $data = '';
    unset($result, $data);
    unset($timer_all[1][$room_id]);
}

function send2room(array $to, $msg) {//向$to的成员发送同一条消息
    global $ws_worker, $connection_all, $timer_all;
    foreach ($to as $k => $v) {
        if (isset($connection_all[$v]) && isset($ws_worker->connections[$connection_all[$v]])) {
            echo "\n当前发送给{$v} 的消息-{$msg}\n";
            $ws_worker->connections[$connection_all[$v]]->send($msg);
        }
    }
}

function https_post($data, $url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_TIMEOUT, 20); // 设置超时限制防止死循环
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charset=utf-8')
    );
    ob_start();
    curl_exec($ch);
    if (curl_errno($ch)) {
        return curl_error($ch); //捕抓异常
    }
    $return_content = ob_get_contents();
    ob_end_clean();
    curl_close($ch);
    return $return_content;
}
